﻿using System;
using System.Runtime.Serialization;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using System.Windows;
using MyBet.Controls;
using System.Collections.Generic;
using MyBet.Web;
using System.ServiceModel.DomainServices.Client;
using System.Threading;
using ParieurPro.DAL;
using MyBet.Class;

namespace MyBet
{
    /// <summary>
    /// Main <see cref="Application"/> class.
    /// </summary>
    public partial class App : Application
    {
        /// <summary>
        /// Tournoi par défaut
        /// TODO : rendre paramétrable les tournois
        /// </summary>
        public const int DefaultContestId = 2;

        private BusyIndicator busyIndicator;
        private static Dictionary<Int32, TeamObject> _teamsCache;
        private static Dictionary<Int32, ChampionshipObject> _championshipsCache;
        private static BetContext _betContext;
        private static SecurityServiceReference.UserObject _currentUser;
        private bool _isCacheLoaded;
        private bool _isTeamsCacheLoaded;
        private bool _isChampionshipsCacheLoaded;
        private static UserRegistrationContext _userRegistrationContext ;
        private static Dictionary<int, EventServiceReference.EventObject> eventsDictionary=new Dictionary<int,EventServiceReference.EventObject>();
        private static int currentEventId;
        private static Dictionary<int, Dictionary<int, RankCache>> _rankCacheDictionary = new Dictionary<int, Dictionary<int, RankCache>>();

        public static Dictionary<int, Dictionary<int,RankCache>> RankCacheDictionary
        {
            get { return App._rankCacheDictionary; }
            set { App._rankCacheDictionary = value; }
        }

        public static int CurrentEventId
        {
            get { return App.currentEventId; }
            set { App.currentEventId = value; }
        }

        public static Dictionary<int, EventServiceReference.EventObject> EventsDictionary
        {
            get { return eventsDictionary; }
            set { eventsDictionary = value; }
        }

        public bool IsChampionshipsCacheLoaded
        {
            get { return _isChampionshipsCacheLoaded; }
            set { _isChampionshipsCacheLoaded = value; }
        }

        public static UserRegistrationContext UserRegistration
        {
            get { return _userRegistrationContext; }
            set { _userRegistrationContext = value; }
        }

        public bool IsTeamsCacheLoaded
        {
            get { return _isTeamsCacheLoaded; }
            set { _isTeamsCacheLoaded = value; }
        }

        public bool IsCacheLoaded
        {
            get { return _isCacheLoaded; }
            set { _isCacheLoaded = value; }
        }

        public static SecurityServiceReference.UserObject CurrentUser
        {
            get { return App._currentUser; }
            set { App._currentUser = value; }
        }
 
        public static BetContext BetContext
        {
            get { return _betContext; }
            set { _betContext = value; }
        }

        /// <summary>
        /// Cache with all teams and images
        /// </summary>
        public static Dictionary<Int32, TeamObject> TeamsCache
        {
            get { return App._teamsCache; }
            set { App._teamsCache = value; }
        }

        public static Dictionary<Int32, ChampionshipObject> ChampionshipsCache
        {
            get { return App._championshipsCache; }
            set { App._championshipsCache = value; }
        }

        /// <summary>
        /// Creates a new <see cref="App"/> instance.
        /// </summary>
        public App()
        {
            IsCacheLoaded = false;
            IsTeamsCacheLoaded = false;
            IsChampionshipsCacheLoaded = false;

            TeamsCache = new Dictionary<int, TeamObject>();
            ChampionshipsCache = new Dictionary<int, ChampionshipObject>();
            InitializeComponent();
            // Create a WebContext and add it to the ApplicationLifetimeObjects
            // collection.  This will then be available as WebContext.Current.
            WebContext webContext = new WebContext();
            webContext.Authentication = new FormsAuthentication();
            //webContext.Authentication = new WindowsAuthentication();
            this.ApplicationLifetimeObjects.Add(webContext);
        }

        private void TeamsLoading_Completed(LoadOperation<TeamObject> operation)
        {
            //bool bInitialize = false;
            if (!operation.IsCanceled)
            {
                if (!operation.HasError)
                {
                    TeamsCache.Clear();
                    foreach (TeamObject t in operation.Entities)
                    {
                        TeamsCache.Add(t.TeamId, t);
                    }
                }
            }

            var queryChampionshipsLoading = BetContext.GetChampionshipsQuery();
            BetContext.Load(queryChampionshipsLoading, ChampionshipLoading_Completed, null);

            //lock (this)
            //{
            //    IsTeamsCacheLoaded = true;
            //    IsCacheLoaded = IsTeamsCacheLoaded && IsChampionshipsCacheLoaded;
            //    bInitialize = IsCacheLoaded;
            //}

            //// Show some UI to the user while LoadUser is in progress
            //if (bInitialize)
            //{
            //    this.InitializeRootVisual();
            //}

        }

        private void ChampionshipLoading_Completed(LoadOperation<ChampionshipObject> operation)
        {
            //bool bInitialize = false;
            if (!operation.IsCanceled)
            {
                if (!operation.HasError)
                {
                    ChampionshipsCache.Clear();
                    foreach (ChampionshipObject c in operation.Entities)
                    {
                        ChampionshipsCache.Add(c.ChampionshipId, c);
                    }
                }
            }

            //lock (this)
            //{
            //    IsChampionshipsCacheLoaded = true;
            //    IsCacheLoaded = IsTeamsCacheLoaded && IsChampionshipsCacheLoaded;
            //    bInitialize = IsCacheLoaded;
            //}

            //// Show some UI to the user while LoadUser is in progress
            //if (bInitialize)
            //{
                this.InitializeRootVisual();
            //}
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // This will enable you to bind controls in XAML files to WebContext.Current
            // properties
            this.Resources.Add("WebContext", WebContext.Current);

            // This will automatically authenticate a user when using windows authentication
            // or when the user chose "Keep me signed in" on a previous login attempt
            WebContext.Current.Authentication.LoadUser(this.Application_UserLoaded, null);

            BetContext = new BetContext();
            // Load Teams cache
            var queryTeamsLoading = BetContext.GetTeamsQuery();
            BetContext.Load(queryTeamsLoading, TeamsLoading_Completed, null);
            
            // Load User registration context
            _userRegistrationContext = new UserRegistrationContext();
        }

        /// <summary>
        /// Invoked when the <see cref="LoadUserOperation"/> completes. Use this
        /// event handler to switch from the "loading UI" you created in
        /// <see cref="InitializeRootVisual"/> to the "application UI"
        /// </summary>
        private void Application_UserLoaded(LoadUserOperation operation)
        {
        }

        /// <summary>
        /// Initializes the <see cref="Application.RootVisual"/> property. The
        /// initial UI will be displayed before the LoadUser operation has completed
        /// (The LoadUser operation will cause user to be logged automatically if
        /// using windows authentication or if the user had selected the "keep
        /// me signed in" option on a previous login).
        /// </summary>
        protected virtual void InitializeRootVisual()
        {
            this.busyIndicator = new BusyIndicator();
            this.busyIndicator.Content = new MainPage();
            this.busyIndicator.HorizontalContentAlignment = HorizontalAlignment.Stretch;
            this.busyIndicator.VerticalContentAlignment = VerticalAlignment.Stretch;
            this.RootVisual = this.busyIndicator;
        }

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            // If the app is running outside of the debugger then report the exception using
            // a ChildWindow control.
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                // NOTE: This will allow the application to continue running after an exception has been thrown
                // but not handled. 
                // For production applications this error handling should be replaced with something that will 
                // report the error to the website and stop the application.
                e.Handled = true;
                ErrorWindow.CreateNew(e.ExceptionObject);
            }
        }
    }
}